﻿using AspNetCoreRateLimit;
using Furion;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NetCoreConsole1.Entities;
using System.Net;

namespace NetCoreConsole1
{

    public class Startup : AppStartup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCorsAccessor();

            #region 限流

            services.Configure<IpRateLimitOptions>(App.Configuration.GetSection("IpRateLimiting"));
            services.Configure<IpRateLimitPolicies>(App.Configuration.GetSection("IpRateLimitPolicies"));

            //configure client rate limiting middleware
            services.Configure<ClientRateLimitOptions>(App.Configuration.GetSection("ClientRateLimiting"));
            services.Configure<ClientRateLimitPolicies>(App.Configuration.GetSection("ClientRateLimitPolicies"));

            // register stores
            services.AddInMemoryRateLimiting();

            services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
            services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();

            #endregion

            services.AddControllers().AddInject();
            services.AddRemoteRequest();
            services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();


            //services.Configure<Options>(App.Configuration.GetSection("options"));

            var options = App.Configuration.GetSection("options").Get<Options>();
            // Add Minio using the custom endpoint and configure additional settings for default MinioClient initialization
            //services.AddMinio(configureClient => configureClient
            //    .WithEndpoint(options.minio.endpoint2)
            //    .WithCredentials(options.minio.accessKey, options.minio.secretKey)
            //    .WithSSL(true)
            //    .Build());
            services.AddHttpContextAccessor();
            // 例子二：每天创建一个日志文件
            services.AddFileLogging("logs/application-{0:yyyy}-{0:MM}-{0:dd}.log",
                options => { options.FileNameRule = fileName => { return string.Format(fileName, DateTime.UtcNow); }; });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // 配置在最前面的中间件
            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
                ForwardLimit = 2, // 根据实际代理层级设置
                KnownProxies =
                {
                    // 添加已知代理服务器IP
                    IPAddress.Parse("192.168.1.1"),
                    IPAddress.Parse("10.19.94.20")
                },
            });
            // 允许所有已知代理（生产环境建议指定具体IP）
            app.ApplicationServices.GetService<ILogger<Program>>()?.LogWarning("允许所有网络作为已知代理");
            app.Use((context, next) =>
            {
                context.Connection.RemoteIpAddress ??= context.Connection.LocalIpAddress;
                return next(context);
            });
            app.UseRouting();
            app.UseCorsAccessor();
            app.UseInject(string.Empty);
            app.UseEndpoints(endpoint => { endpoint.MapControllers(); });
            //限流
            app.UseIpRateLimiting();
            app.UseClientRateLimiting();
        }
    }
}